﻿#include "FITKAcousticsMaterialMgrAdaptor.h"
#include "FITKAcousticsHDF5Writer.h"
#include "FITKAcousticsHDF5Reader.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsMaterialsFluid.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsMaterialsIsosolid.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsMaterialsViscoElastic.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsMaterialsFoam.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsMaterialsFiber.h"
#include "FITK_Interface/FITKInterfaceIO/FITKHDF5FileTool.h"
#include <H5Cpp.h>

namespace IO
{
    bool FITKAcousticsMaterialMgrAdaptor::adaptR()
    {
        Acoustics::FITKAcousticsMaterialManager* materialMgr =
            dynamic_cast<Acoustics::FITKAcousticsMaterialManager*>(_dataObj);
        if (materialMgr == nullptr) return false;
        m_toolp = _reader->getHDF5FileTool();//初始化工具
        if (m_toolp == nullptr)
        {
            return false;
        }

        std::tuple<bool, H5::Group>Ret = m_toolp->openGp("Material");
        if (std::get<0>(Ret) == false) { return false; }
        H5::Group MaterialGroup = std::get<1>(Ret);

        bool FluidRet = this->readFluidMaterials(MaterialGroup, materialMgr);
        bool IsotropicSolidRet = this->readIsotropicSolids(MaterialGroup, materialMgr);
        bool ViscoElasticRet = this->readViscoElasticss(MaterialGroup, materialMgr);
        bool FoamRet = this->readFoam(MaterialGroup, materialMgr);
        bool FiberRet = this->readFiber(MaterialGroup, materialMgr);
        return FluidRet && IsotropicSolidRet&&ViscoElasticRet&&FoamRet&&FiberRet;
    }

    bool FITKAcousticsMaterialMgrAdaptor::adaptW()
    {
        Acoustics::FITKAcousticsMaterialManager* materialMgr =
            dynamic_cast<Acoustics::FITKAcousticsMaterialManager*>(_dataObj);
        if (materialMgr == nullptr || _writer == nullptr) return false;
        m_toolp = _writer->getHDF5FileTool();//初始化工具

        //获取流体数据
        QList<Acoustics::FITKAcousticsAbsMaterial*>Fluids = materialMgr->getAcousticsMaterials(Acoustics::FITKAcousticsAbsMaterial::AcousticsMaterialType::Fluid);
        //获取各向同性固体数据
        QList<Acoustics::FITKAcousticsAbsMaterial*>ISOSolids = materialMgr->getAcousticsMaterials(Acoustics::FITKAcousticsAbsMaterial::AcousticsMaterialType::ISOSolid);
        //获取粘弹性数据
        QList<Acoustics::FITKAcousticsAbsMaterial*>ViscoElastics = materialMgr->getAcousticsMaterials(Acoustics::FITKAcousticsAbsMaterial::AcousticsMaterialType::ViscoElastic);
        //获取泡沐数据
        QList<Acoustics::FITKAcousticsAbsMaterial*>Foams = materialMgr->getAcousticsMaterials(Acoustics::FITKAcousticsAbsMaterial::AcousticsMaterialType::Foam);
        //获取纤维数据
        QList<Acoustics::FITKAcousticsAbsMaterial*>Fibers = materialMgr->getAcousticsMaterials(Acoustics::FITKAcousticsAbsMaterial::AcousticsMaterialType::Fiber);


        std::tuple<bool, H5::Group> Ret = m_toolp->createGp("Material");     //创建材料组
        if (std::get<0>(Ret) == false) { return false; }
        H5::Group MaterialGroup = std::get<1>(Ret);


        bool FluidRet = this->writeFluidMaterials(MaterialGroup, Fluids);               //写流体
        bool IsotropicSolidRet = this->writeIsotropicSolids(MaterialGroup, ISOSolids);  //写各向同性固体
        bool ViscoElasticRet = this->writeViscoElastics(MaterialGroup, ViscoElastics);  //写粘弹性
        bool FoamRet = this->writeFoam(MaterialGroup, Foams);                           //写泡沐
        bool FiberRet = this->writeFibers(MaterialGroup, Fibers);                       //写纤维
        return FluidRet && IsotropicSolidRet&&ViscoElasticRet&&FoamRet&&FiberRet;
    }
    bool FITKAcousticsMaterialMgrAdaptor::readIsotropicSolids(H5::Group & MaterialGroup, Acoustics::FITKAcousticsMaterialManager * mager)
    {
        const char *ISOSolidName = "ISOSolid";
        const char *ISOSolidCountName = "ISOSolidCount";

        std::tuple<bool, H5::Group>Ret = m_toolp->openGp(MaterialGroup, ISOSolidName);//打开各向同性组
        if (std::get<0>(Ret) == false) { return false; }
        H5::Group ISOSolidGroup = std::get<1>(Ret);

        std::tuple<bool, H5::Attribute>RetAttr = m_toolp->openAttribut(ISOSolidGroup, ISOSolidCountName); //打开各向同性组个数属性
        if (std::get<0>(RetAttr) == false) { return false; }
        H5::Attribute CountAttrattr = std::get<1>(RetAttr);

        int count = -1;
        CountAttrattr.read(H5::PredType::NATIVE_INT, &count);
        for (int i = 0; i < count; ++i)
        {
            //通过转换i为str，获取该str属性下对应组的名称(具体材料名称Air)
            std::string subGroupName = m_toolp->readGroupAttrName(ISOSolidGroup, i);
            //打开子组
            std::tuple<bool, H5::Group>RetISOSolidsub = m_toolp->openGp(ISOSolidGroup, subGroupName.data());
            if (std::get<0>(RetISOSolidsub) == false) { continue; }//打不开则退出此次
            H5::Group subGroup = std::get<1>(RetISOSolidsub);

            std::string Name{};             //该类各向同性材料名称
            double Density = 0.0;           //密度
            double TensileModulus = 0.0;    //拉伸模量
            double ShearModulus = 0.0;      //剪切模量
            double PoissonRatio = 0.0;      //泊松比
            std::string Describe{};         //材料描述
            int ID = -1;                    //数据ID

            Name = subGroupName;
            m_toolp->readGroupDouble(subGroup, "Density", &Density);
            m_toolp->readGroupDouble(subGroup, "TensileModulus", &TensileModulus);
            m_toolp->readGroupDouble(subGroup, "ShearModulus", &ShearModulus);
            m_toolp->readGroupDouble(subGroup, "PoissonRatio", &PoissonRatio);
            m_toolp->readGroupStr(subGroup, "Des", Describe);
            m_toolp->readGroupint(subGroup, "ID", &ID);

            Acoustics::FITKAcousticsMaterialsIsosolid*IsosolidData = new Acoustics::FITKAcousticsMaterialsIsosolid();//由框架负责释放
            if (IsosolidData==nullptr)
            {
                continue;
            }
            IsosolidData->setDensity(Density);
            IsosolidData->setTensileModulus(TensileModulus);
            IsosolidData->setShearModulus(ShearModulus);
            IsosolidData->setPoissonRatio(PoissonRatio);
            IsosolidData->setMaterialDescribe(RestoreStr(Describe));
            IsosolidData->setDataObjectName(RestoreStr(Name));

            Core::FITKAbstractDataIDAlter a;
            a.modifyDataID(IsosolidData, ID);
            mager->appendDataObj(IsosolidData);
        }
        return true;
    }
    bool FITKAcousticsMaterialMgrAdaptor::readViscoElasticss(H5::Group & MaterialGroup, Acoustics::FITKAcousticsMaterialManager * mager)
    {
        if (mager==nullptr)
        {
            return false;
        }
        std::tuple<bool, H5::Group>Ret = m_toolp->openGp(MaterialGroup, "ViscoElastic");//打开组
        if (std::get<0>(Ret) == false) { return false; }
        H5::Group ViscoElasticGroup = std::get<1>(Ret);

        std::tuple<bool, H5::Attribute>RetAttr = m_toolp->openAttribut(ViscoElasticGroup, "ViscoElasticCount"); //打开各向同性组个数属性
        if (std::get<0>(RetAttr) == false) { return false; }
        H5::Attribute CountAttrattr = std::get<1>(RetAttr);

        int count = -1;
        CountAttrattr.read(H5::PredType::NATIVE_INT, &count);
        for (int i = 0; i < count; ++i)
        {
            //通过转换i为str，获取该str属性下对应组的名称(具体材料名称Air)
            std::string subGroupName = m_toolp->readGroupAttrName(ViscoElasticGroup, i);
            //打开子组
            std::tuple<bool, H5::Group>RetISOSolidsub = m_toolp->openGp(ViscoElasticGroup, subGroupName.data());
            if (std::get<0>(RetISOSolidsub) == false) { continue; }//打不开则退出此次
            H5::Group subGroup = std::get<1>(RetISOSolidsub);

            std::string Name{};
            double Density = 0.0;
            double PoissonsRatio = 0.0;
            int ShearModulusSpectrumID = 0;
            int DampingSpectrumID = 0;
            std::string Describe{};
            int ID = -1;


            Name = subGroupName;
            m_toolp->readGroupDouble(subGroup, "Density", &Density);
            m_toolp->readGroupDouble(subGroup, "PoissonsRatio", &PoissonsRatio);
            m_toolp->readGroupint(subGroup, "ShearModulusSpectrumID", &ShearModulusSpectrumID);
            m_toolp->readGroupint(subGroup, "DampingSpectrumID", &DampingSpectrumID);
            m_toolp->readGroupStr(subGroup, "Des", Describe);
            m_toolp->readGroupint(subGroup, "ID", &ID);

            Acoustics::FITKAcousticsMaterialsViscoElastic*ViscoElasticData = new Acoustics::FITKAcousticsMaterialsViscoElastic();
            if (ViscoElasticData==nullptr)
            {
                continue;
            }
            ViscoElasticData->setDataObjectName(RestoreStr(Name));
            ViscoElasticData->setDensity(Density);
            ViscoElasticData->setPoissonsRatio(PoissonsRatio);
            ViscoElasticData->setMaterialDescribe(RestoreStr(Describe));
            ViscoElasticData->setShearModulusSpectrumID(ShearModulusSpectrumID);
            ViscoElasticData->setDampingSpectrumID(DampingSpectrumID);

            Core::FITKAbstractDataIDAlter a;
            a.modifyDataID(ViscoElasticData, ID);
            mager->appendDataObj(ViscoElasticData);
        }
        return true;
    }
    bool FITKAcousticsMaterialMgrAdaptor::readFoam(H5::Group & MaterialGroup, Acoustics::FITKAcousticsMaterialManager * mager)
    {
        if (mager==nullptr)
        {
            return false;
        }
        std::tuple<bool, H5::Group>Ret = m_toolp->openGp(MaterialGroup, "Foam");//打开组
        if (std::get<0>(Ret) == false) { return false; }
        H5::Group thisMaterialsGroup = std::get<1>(Ret);

        std::tuple<bool, H5::Attribute>RetAttr = m_toolp->openAttribut(thisMaterialsGroup, "FoamCount"); //打开各向同性组个数属性
        if (std::get<0>(RetAttr) == false) { return false; }
        H5::Attribute CountAttrattr = std::get<1>(RetAttr);

        int count = -1;
        CountAttrattr.read(H5::PredType::NATIVE_INT, &count);
        for (int i = 0; i < count; ++i)
        {
            //通过转换i为str，获取该str属性下对应组的名称(具体材料名称Air)
            std::string subGroupName = m_toolp->readGroupAttrName(thisMaterialsGroup, i);
            //打开子组
            std::tuple<bool, H5::Group>RetGroup = m_toolp->openGp(thisMaterialsGroup, subGroupName.data());
            if (std::get<0>(RetGroup) == false) { continue; }//打不开则退出此次
            H5::Group subGroup = std::get<1>(RetGroup);


            std::string Name{};
            double Density = 0.0;
            double FlowResistivity = 0.0;//静态流阻率
            double Porosity = 0.0;
            double shearModulus = 0.0;
            double Tortuosity = 0.0;
            double ViscousLength = 0.0;//弹性特征长度
            double ThermalLength = 0.0;//热特征长度
            double LossFactor = 0.0;
            double TensileModulus = 0.0;//拉伸模量（杨氏模量）
            double PoissonRatio = 0.0;
            std::string Describe{};
            int ID = -1;


            Name = subGroupName;
            m_toolp->readGroupDouble(subGroup, "Density", &Density);
            m_toolp->readGroupDouble(subGroup, "FlowResistivity", &FlowResistivity);
            m_toolp->readGroupDouble(subGroup, "Porosity", &Porosity);
            m_toolp->readGroupDouble(subGroup, "shearModulus", &shearModulus);
            m_toolp->readGroupDouble(subGroup, "Tortuosity", &Tortuosity);
            m_toolp->readGroupDouble(subGroup, "ViscousLength", &ViscousLength);
            m_toolp->readGroupDouble(subGroup, "ThermalLength", &ThermalLength);
            m_toolp->readGroupDouble(subGroup, "LossFactor", &LossFactor);
            m_toolp->readGroupDouble(subGroup, "TensileModulus", &TensileModulus);
            m_toolp->readGroupDouble(subGroup, "PoissonRatio", &PoissonRatio);
            m_toolp->readGroupStr(subGroup, "Des", Describe);
            m_toolp->readGroupint(subGroup, "ID", &ID);

            //构建泡沐材料类，并填充数据
            Acoustics::FITKAcousticsMaterialsFoam*newObjData = new Acoustics::FITKAcousticsMaterialsFoam();
            if (newObjData==nullptr)
            {
                continue;
            }
            newObjData->setDataObjectName(RestoreStr(Name));
            newObjData->setDensity(Density);
            newObjData->setFlowResistivity(FlowResistivity);
            newObjData->setPorosity(Porosity);
            newObjData->setshearModulus(shearModulus);
            newObjData->setTortuosity(Tortuosity);
            newObjData->setViscousLength(ViscousLength);
            newObjData->setThermalLength(ThermalLength);
            newObjData->setLossFactor(LossFactor);
            newObjData->setTensileModulus(TensileModulus);
            newObjData->setPoissonRatio(PoissonRatio);
            newObjData->setMaterialDescribe(RestoreStr(Describe));

            Core::FITKAbstractDataIDAlter a;
            a.modifyDataID(newObjData, ID);
            mager->appendDataObj(newObjData);
        }
        return true;
    }
    bool FITKAcousticsMaterialMgrAdaptor::readFiber(H5::Group & MaterialGroup, Acoustics::FITKAcousticsMaterialManager * mager)
    {
        std::tuple<bool, H5::Group>Ret = m_toolp->openGp(MaterialGroup, "Fiber");//打开组
        if (std::get<0>(Ret) == false) { return false; }
        H5::Group thisMaterialsGroup = std::get<1>(Ret);

        std::tuple<bool, H5::Attribute>RetAttr = m_toolp->openAttribut(thisMaterialsGroup, "FiberCount"); //打开各向同性组个数属性
        if (std::get<0>(RetAttr) == false) { return false; }
        H5::Attribute CountAttrattr = std::get<1>(RetAttr);

        int count = -1;
        CountAttrattr.read(H5::PredType::NATIVE_INT, &count);
        for (int i = 0; i < count; ++i)
        {
            //通过转换i为str，获取该str属性下对应组的名称(具体材料名称Air)
            std::string subGroupName = m_toolp->readGroupAttrName(thisMaterialsGroup, i);
            //打开子组
            std::tuple<bool, H5::Group>RetGroup = m_toolp->openGp(thisMaterialsGroup, subGroupName.data());
            if (std::get<0>(RetGroup) == false) { continue; }//打不开则退出此次
            H5::Group subGroup = std::get<1>(RetGroup);


            std::string Name{};
            double Density = 0.0;
            double FlowResistivity = 0.0;//静态流阻率
            double Porosity = 0.0;
            double Tortuosity = 0.0;
            double ViscousLength = 0.0;//弹性特征长度
            double ThermalLength = 0.0;//热特征长度
            std::string Describe{};
            int ID = -1;


            Name = subGroupName;
            m_toolp->readGroupDouble(subGroup, "Density", &Density);
            m_toolp->readGroupDouble(subGroup, "FlowResistivity", &FlowResistivity);
            m_toolp->readGroupDouble(subGroup, "Porosity", &Porosity);
            m_toolp->readGroupDouble(subGroup, "Tortuosity", &Tortuosity);
            m_toolp->readGroupDouble(subGroup, "ViscousLength", &ViscousLength);
            m_toolp->readGroupDouble(subGroup, "ThermalLength", &ThermalLength);
            m_toolp->readGroupStr(subGroup, "Des", Describe);
            m_toolp->readGroupint(subGroup, "ID", &ID);

            //构建泡沐材料类，并填充数据
            Acoustics::FITKAcousticsMaterialsFiber*newObjData = new Acoustics::FITKAcousticsMaterialsFiber();
            newObjData->setDataObjectName(RestoreStr(Name));
            newObjData->setDensity(Density);
            newObjData->setFlowResistivity(FlowResistivity);
            newObjData->setPorosity(Porosity);
            newObjData->setTortuosity(Tortuosity);
            newObjData->setViscousLength(ViscousLength);
            newObjData->setThermalLength(ThermalLength);
            newObjData->setMaterialDescribe(RestoreStr(Describe));

            Core::FITKAbstractDataIDAlter a;
            a.modifyDataID(newObjData, ID);
            mager->appendDataObj(newObjData);
        }
        return true;
    }
    bool FITKAcousticsMaterialMgrAdaptor::areAllTrue(const std::vector<bool>& Data)
    {
        return std::all_of(Data.begin(), Data.end(), [](bool b) { return b; });
    }

    QString FITKAcousticsMaterialMgrAdaptor::RestoreStr(std::string data)
    {
        QString CheckStr = QString::fromStdString(data);
        m_toolp->RestoreString(CheckStr);//检查是否原来有字符/，有则转换
        return CheckStr;
    }

    QString FITKAcousticsMaterialMgrAdaptor::FluidTypeToStr(Acoustics::FITKAcousticsMaterialsFluid::FluidType type)
    {
        switch (type)
        {
        case Acoustics::FITKAcousticsMaterialsFluid::Gas:
        {
            return "Gas";
            break;
        }
            
        case Acoustics::FITKAcousticsMaterialsFluid::Liquid:
        {
            return "Liquid";
            break;
        }
        default:
            break;
        }
    }

    Acoustics::FITKAcousticsMaterialsFluid::FluidType FITKAcousticsMaterialMgrAdaptor::StrFromFluidType(QString type)
    {
        if (type=="Gas")
        {
            return Acoustics::FITKAcousticsMaterialsFluid::FluidType::Gas;
        }
        else if(type == "Liquid")
        {
            return Acoustics::FITKAcousticsMaterialsFluid::FluidType::Liquid;
        }
    }


    bool FITKAcousticsMaterialMgrAdaptor::writeFoam(H5::Group & MaterialGroup, QList<Acoustics::FITKAcousticsAbsMaterial*> Foams)
    {
        //创建的HDF5目录结构
        const char *Path = "Material/Foam";

        //数据有多少行 (二维表格)
        int count = Foams.size();

        //在材料组下创建组，并为组附加数据个数属性,此时结构Material/Foam
        m_toolp->CreateGroupAndAttr(MaterialGroup, "Foam", "FoamCount", count);

        //获取刚刚创建的组
        H5::Group thisGroup = m_toolp->GetPathGroup(Path);

        for (int i = 0; i < count; ++i)
        {
            //转换为子类
            Acoustics::FITKAcousticsMaterialsFoam* ObjP = dynamic_cast<Acoustics::FITKAcousticsMaterialsFoam*>(Foams.at(i));

            if (ObjP == nullptr)
            {
                continue;
            }
            //获取所有一行需要写入的数据
            QString Name = ObjP->getDataObjectName();
            double Density = ObjP->getDensity();
            double FlowResistivity = ObjP->getFlowResistivity();//静态流阻率
            double Porosity = ObjP->getPorosity();
            double shearModulus = ObjP->getshearModulus();
            double Tortuosity = ObjP->getTortuosity();
            double ViscousLength = ObjP->getViscousLength();//弹性特征长度
            double ThermalLength = ObjP->getThermalLength();//热特征长度
            double LossFactor = ObjP->getLossFactor();
            double TensileModulus = ObjP->getTensileModulus();//拉伸模量（杨氏模量）
            double PoissonRatio = ObjP->getPoissonRatio();
            QString Describe = ObjP->getMaterialDescribe();
            int ID = ObjP->getDataObjectID();

            //检查字符串输入是否有特殊字符
            m_toolp->CheckString(Name);
            m_toolp->CheckString(Describe);

            //在材料组下创建具体材料属性,并绑定到组
            m_toolp->CreateNameFromAttr(thisGroup, i, Name.toStdString());

            std::tuple<bool, H5::Group>Ret = m_toolp->createGp(thisGroup, Name);//创建子节点1
            if (std::get<0>(Ret) == false) { continue; }

            H5::Group subGroup = std::get<1>(Ret);

            std::vector<bool>writeResultBools;//存储此次写入时返回成功与否数据
            //将材料数据写入到具体材料的属性中

            writeResultBools.push_back(m_toolp->writeGroupAttrStr(subGroup, "Name", Name.toStdString()));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "Density", Density));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "FlowResistivity", FlowResistivity));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "Porosity", Porosity));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "shearModulus", shearModulus));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "Tortuosity", Tortuosity));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "ViscousLength", ViscousLength));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "ThermalLength", ThermalLength));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "LossFactor", LossFactor));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "TensileModulus", TensileModulus));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "PoissonRatio", PoissonRatio));
            writeResultBools.push_back(m_toolp->writeGroupAttrStr(subGroup, "Describe", Describe.toStdString()));
            writeResultBools.push_back(m_toolp->writeGroupAttrInt(subGroup, "ID", ID));//写入数据对象ID
            bool allBool = this->areAllTrue(writeResultBools);
            if (allBool == false)
            {
                //如果不是全部都为true则，写入失败，写该数据终止
                return false;
            }
        }
        return true;
    }

    bool FITKAcousticsMaterialMgrAdaptor::writeFibers(H5::Group & MaterialGroup, QList<Acoustics::FITKAcousticsAbsMaterial*> Fibers)
    {
        //创建的HDF5目录结构
        const char *Path = "Material/Fiber";

        //数据有多少行 (二维表格)
        int count = Fibers.size();

        //在材料组下创建流体组，并为流体组附加流体数据个数属性,此时结构Material/Fiber
        m_toolp->CreateGroupAndAttr(MaterialGroup, "Fiber", "FiberCount", count);

        //获取刚刚创建的组
        H5::Group thisGroup = m_toolp->GetPathGroup(Path);

        for (int i = 0; i < count; ++i)
        {
            //转换为子类
            Acoustics::FITKAcousticsMaterialsFiber* ObjP = dynamic_cast<Acoustics::FITKAcousticsMaterialsFiber*>(Fibers.at(i));

            if (ObjP == nullptr)
            {
                continue;
            }
            //获取所有一行需要写入的数据
            QString Name = ObjP->getDataObjectName();
            double Density = ObjP->getDensity();
            double FlowResistivity = ObjP->getFlowResistivity();//静态流阻率
            double Porosity = ObjP->getPorosity();
            double Tortuosity = ObjP->getTortuosity();
            double ViscousLength = ObjP->getViscousLength();//弹性特征长度
            double ThermalLength = ObjP->getThermalLength();//热特征长度
            QString Describe = ObjP->getMaterialDescribe();
            int ID = ObjP->getDataObjectID();

            //检查字符串输入是否有特殊字符
            m_toolp->CheckString(Name);
            m_toolp->CheckString(Describe);

            //在材料组下创建具体材料属性,并绑定到组
            m_toolp->CreateNameFromAttr(thisGroup, i, Name.toStdString());

            std::tuple<bool, H5::Group>Ret = m_toolp->createGp(thisGroup, Name);//创建子节点1
            if (std::get<0>(Ret) == false) { continue; }

            H5::Group subGroup = std::get<1>(Ret);

            std::vector<bool>writeResultBools;//存储此次写入时返回成功与否数据
            //将材料数据写入到具体材料的属性中

            writeResultBools.push_back(m_toolp->writeGroupAttrStr(subGroup, "Name", Name.toStdString()));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "Density", Density));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "FlowResistivity", FlowResistivity));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "Porosity", Porosity));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "Tortuosity", Tortuosity));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "ViscousLength", ViscousLength));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "ThermalLength", ThermalLength));
            writeResultBools.push_back(m_toolp->writeGroupAttrStr(subGroup, "Describe", Describe.toStdString()));
            writeResultBools.push_back(m_toolp->writeGroupAttrInt(subGroup, "ID", ID));//写入数据对象ID
            bool allBool = this->areAllTrue(writeResultBools);
            if (allBool == false)
            {
                //如果不是全部都为true则，写入失败，写该数据终止
                return false;
            }
        }
        return true;
    }

    bool FITKAcousticsMaterialMgrAdaptor::writeFEMaterial(H5::Group & MaterialGroup, QList<Acoustics::FITKAcousticsAbsMaterial*> FEMaterials)
    {
        //暂未有该数据结构
        return true;
    }

    bool FITKAcousticsMaterialMgrAdaptor::readFluidMaterials(H5::Group &MaterialGroup, Acoustics::FITKAcousticsMaterialManager*mager)
    {
        const char *FluidGroupName = "Fluids";      //流体组
        const char *FluidsCountName = "FluidsCount";//流体组个数

        std::tuple<bool, H5::Group>Ret = m_toolp->openGp(MaterialGroup, FluidGroupName);//打开流体组
        if (std::get<0>(Ret) == false) { return false; }
        H5::Group FluidsGroup = std::get<1>(Ret);

        //读取"FluidsCount"属性获取材料数量
        std::tuple<bool, H5::Attribute>RetAttr = m_toolp->openAttribut(FluidsGroup, FluidsCountName);
        if (std::get<0>(RetAttr) == false) { return false; }
        H5::Attribute CountAttrattr = std::get<1>(RetAttr);

        int count = -1;
        CountAttrattr.read(H5::PredType::NATIVE_INT, &count);

        //循环读取每个子组的信息
        for (int i = 0; i < count; ++i)
        {
            //通过转换i为str，获取该str属性下对应组的名称(具体材料名称Air)
            std::string subGroupName = m_toolp->readGroupAttrName(FluidsGroup, i);
            //打开子组
            std::tuple<bool, H5::Group>Ret = m_toolp->openGp(FluidsGroup, subGroupName.data());
            if (std::get<0>(Ret) == false) { continue; }
            H5::Group subGroup = std::get<1>(Ret);

            //过程变量
            double SpeedOfSound = 0.0;
            double Density = 0.0;
            double ViscosGroup = 0.0;
            double SpecificHeatsRatio = 0.0;
            double PrandtlNumber = 0.0;
            double MolecularMass = 0.0;
            int id = -1;
            std::vector<float>Color;
            std::string Des;
            std::vector<bool>readResultBools;//存储此次读取时返回成功与否数据
            std::string TypeStr = "";

            //dataSet
            readResultBools.push_back(m_toolp->ReadOneDArrayDataSetFloat(subGroup, "Color", Color));//读取DataSet中颜色
            readResultBools.push_back(m_toolp->readGroupDouble(subGroup, "Speed", &SpeedOfSound));
            readResultBools.push_back(m_toolp->readGroupDouble(subGroup, "Density", &Density));
            readResultBools.push_back(m_toolp->readGroupDouble(subGroup, "Viscos", &ViscosGroup));
            readResultBools.push_back(m_toolp->readGroupDouble(subGroup, "SpecificHeatsRatio", &SpecificHeatsRatio));
            readResultBools.push_back(m_toolp->readGroupDouble(subGroup, "PrandtlNumber", &PrandtlNumber));
            readResultBools.push_back(m_toolp->readGroupDouble(subGroup, "MolecularMass", &MolecularMass));
            readResultBools.push_back(m_toolp->readGroupStr(subGroup, "Des", Des));
            readResultBools.push_back(m_toolp->readGroupStr(subGroup, "TypeStr", TypeStr));
            readResultBools.push_back(m_toolp->readGroupint(subGroup, "ID", &id));

            Acoustics::FITKAcousticsMaterialsFluid::FluidType type=this->StrFromFluidType(QString::fromStdString(TypeStr));

            bool allBool = this->areAllTrue(readResultBools);
            if (allBool == false)
            {
                //如果不是全部都为true则，写入失败，写该数据终止
                return false;
            }
            Acoustics::FITKAcousticsMaterialsFluid*FluidData = new Acoustics::FITKAcousticsMaterialsFluid();//由框架负责释放
            if (FluidData == nullptr)
            {
                continue;
            }
            FluidData->setDensity(Density);
            FluidData->setSpeedOfSound(SpeedOfSound);
            FluidData->setKinematicViscosity(ViscosGroup);
            FluidData->setSpecificHeatsRatio(SpecificHeatsRatio);
            FluidData->setPrandtlNumber(PrandtlNumber);
            FluidData->setMolecularMass(MolecularMass);
            FluidData->setType(type);
            if (Color.size() == 3)
            {
                FluidData->setColor(Color.at(0), Color.at(1), Color.at(2));
            }
            //检查是否原来有字符/有则转换
            FluidData->setDataObjectName(RestoreStr(subGroupName));
            FluidData->setMaterialDescribe(RestoreStr(Des));

            Core::FITKAbstractDataIDAlter a;
            a.modifyDataID(FluidData, id);
            mager->appendDataObj(FluidData);
        }

        return true;
    }


    bool FITKAcousticsMaterialMgrAdaptor::writeFluidMaterials(H5::Group &MaterialGroup, QList<Acoustics::FITKAcousticsAbsMaterial*>Fluids)
    {
        //创建的HDF5目录结构
        const char *Path = "Material/Fluids";

        const char *FluidGroupName = "Fluids";      //流体组
        const char *FluidsCountName = "FluidsCount";//流体组个数

        //数据有多少行 (二维表格)
        int count = Fluids.size();

        //在材料组下创建流体组，并为流体组附加流体数据个数属性,此时结构Material/Fluids
        m_toolp->CreateGroupAndAttr(MaterialGroup, FluidGroupName, FluidsCountName, count);

        //获取刚刚创建的流体组
        H5::Group FluidsGroup = m_toolp->GetPathGroup(Path);

        for (int i = 0; i < count; ++i)
        {
            //转换为子类
            Acoustics::FITKAcousticsMaterialsFluid* FluidObjP = dynamic_cast<Acoustics::FITKAcousticsMaterialsFluid*>(Fluids.at(i));

            if (FluidObjP == nullptr)
            {
                continue;
            }
            //获取所有一行需要写入的数据
            QString Name = FluidObjP->getDataObjectName();                  //获取该类流体材料名称
            double SpeedOfSound = FluidObjP->getSpeedOfSound();             //获取声速
            double Density = FluidObjP->getDensity();                       //获取密度
            double Viscosity = FluidObjP->getKinematicViscosity();          //运动粘度
            double SpecificHeatsRatio = FluidObjP->getSpecificHeatsRatio(); //比热比
            double PrandtlNumber = FluidObjP->getPrandtlNumber();           //普朗特数
            double MolecularMass = FluidObjP->getMolecularMass();           //获取摩尔质量
            QString Describe = FluidObjP->getMaterialDescribe();            //材料描述
            Acoustics::FITKAcousticsMaterialsFluid::FluidType ObjType = FluidObjP->getType();//类型
            QString TypeStr = this->FluidTypeToStr(ObjType);
            
            float Color[3] = { 0.0,0.0,0.0 };
            FluidObjP->getColor(Color);                                  //表格颜色数据
            int ID = FluidObjP->getDataObjectID();                       //获取数据ID

            //检查是否有/如果有，处理为特殊字符串
            m_toolp->CheckString(Name);
            m_toolp->CheckString(Describe);
            //在流体组下创建具体流体材料属性,并绑定到流体组
            m_toolp->CreateNameFromAttr(FluidsGroup, i, Name.toStdString());


            //在流体组下创建具体流体材料数据组此时结构 Material/Fluids(Air(属性))
            H5::Group subGroup = FluidsGroup.createGroup(Name.toStdString());//创建子节点

            std::vector<bool>writeResultBools;//存储此次写入时返回成功与否数据
            //将材料数据写入到具体材料的属性中
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "Speed", SpeedOfSound));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "Density", Density));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "Viscos", Viscosity));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "SpecificHeatsRatio", SpecificHeatsRatio));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "PrandtlNumber", PrandtlNumber));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "MolecularMass", MolecularMass));
            writeResultBools.push_back(m_toolp->writeGroupAttrStr(subGroup, "Des", Describe.toStdString()));
            writeResultBools.push_back(m_toolp->writeGroupAttrStr(subGroup, "TypeStr", TypeStr.toStdString()));
            writeResultBools.push_back(m_toolp->writeGroupAttrInt(subGroup, "ID", ID));//写入数据对象ID
            //向dataSet写入Color
            writeResultBools.push_back(m_toolp->CreateOneDArrayDataSetFloat(subGroup, 3, "Color", Color));
            bool allBool = this->areAllTrue(writeResultBools);
            if (allBool == false)
            {
                //如果不是全部都为true则，写入失败，写该数据终止
                return false;
            }
        }
        return true;
    }

    bool FITKAcousticsMaterialMgrAdaptor::writeViscoElastics(H5::Group & MaterialGroup, QList<Acoustics::FITKAcousticsAbsMaterial*> ViscoElastics)
    {
        //创建的HDF5目录结构
        const char *Path = "Material/ViscoElastic";

        //数据有多少行 (二维表格)
        int count = ViscoElastics.size();

        //在材料组下创建流体组，并为流体组附加流体数据个数属性,此时结构Material/Fluids
        m_toolp->CreateGroupAndAttr(MaterialGroup, "ViscoElastic", "ViscoElasticCount", count);

        //获取刚刚创建的流体组
        H5::Group ViscoElasticsGroup = m_toolp->GetPathGroup(Path);
        //获取刚刚创建的各向同性组

        for (int i = 0; i < count; ++i)
        {
            //转换为子类
            Acoustics::FITKAcousticsMaterialsViscoElastic* ViscoElasticObjP = dynamic_cast<Acoustics::FITKAcousticsMaterialsViscoElastic*>(ViscoElastics.at(i));

            if (ViscoElasticObjP == nullptr)
            {
                continue;
            }
            //获取所有一行需要写入的数据
            QString Name = ViscoElasticObjP->getDataObjectName();
            double Density = ViscoElasticObjP->getDensity();
            double PoissonsRatio = ViscoElasticObjP->getPoissonsRatio();
            int ShearModulusSpectrumID = ViscoElasticObjP->getShearModulusSpectrumID();
            int DampingSpectrumID = ViscoElasticObjP->getDampingSpectrumID();
            QString Describe = ViscoElasticObjP->getMaterialDescribe();
            int ID = ViscoElasticObjP->getDataObjectID();


            //检查字符串输入是否有特殊字符
            m_toolp->CheckString(Name);
            m_toolp->CheckString(Describe);

            //在材料组下创建具体材料属性,并绑定到组
            m_toolp->CreateNameFromAttr(ViscoElasticsGroup, i, Name.toStdString());

            std::tuple<bool, H5::Group>Ret = m_toolp->createGp(ViscoElasticsGroup, Name);//创建子节点1
            if (std::get<0>(Ret) == false) { continue; }

            H5::Group subGroup = std::get<1>(Ret);

            std::vector<bool>writeResultBools;//存储此次写入时返回成功与否数据
            //将材料数据写入到具体材料的属性中
            writeResultBools.push_back(m_toolp->writeGroupAttrStr(subGroup, "Name", Name.toStdString()));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "Density", Density));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "PoissonsRatio", PoissonsRatio));
            writeResultBools.push_back(m_toolp->writeGroupAttrInt(subGroup, "ShearModulusSpectrumID", ShearModulusSpectrumID));
            writeResultBools.push_back(m_toolp->writeGroupAttrInt(subGroup, "DampingSpectrumID", DampingSpectrumID));
            writeResultBools.push_back(m_toolp->writeGroupAttrStr(subGroup, "Describe", Describe.toStdString()));
            writeResultBools.push_back(m_toolp->writeGroupAttrInt(subGroup, "ID", ID));//写入数据对象ID
            bool allBool = this->areAllTrue(writeResultBools);
            if (allBool == false)
            {
                //如果不是全部都为true则，写入失败，写该数据终止
                return false;
            }
        }
        return true;
    }

    bool FITKAcousticsMaterialMgrAdaptor::writeIsotropicSolids(H5::Group & MaterialGroup, QList<Acoustics::FITKAcousticsAbsMaterial*>IsotropicSolids)
    {
        //创建的HDF5目录结构
        const char *Path = "Material/ISOSolid";

        //定义各向同性下Group组名称
        const char *ISOSolidName = "ISOSolid";
        const char *ISOSolidCountName = "ISOSolidCount";

        int count = IsotropicSolids.size();
        //在材料组下创建各向同性组，并为各向同性组附加各向同性组数据个数属性,此时结构Material/ISOSolid
        m_toolp->CreateGroupAndAttr(MaterialGroup, ISOSolidName, ISOSolidCountName, count);

        //获取刚刚创建的各向同性组
        H5::Group ISOSolidGroup = m_toolp->GetPathGroup(Path);

        for (int i = 0; i < count; ++i)
        {
            //转换为子类
            Acoustics::FITKAcousticsMaterialsIsosolid* ISOSolidObjP = static_cast<Acoustics::FITKAcousticsMaterialsIsosolid*>(IsotropicSolids.at(i));
            if (ISOSolidObjP == nullptr)
            {
                continue;
            }
            //获取所有一行需要写入的数据
            QString Name = ISOSolidObjP->getDataObjectName();         //获取该类各向同性材料名称
            double Density = ISOSolidObjP->getDensity();              //获取密度
            double TensileModulus = ISOSolidObjP->getTensileModulus();//获取拉伸模量
            double ShearModulus = ISOSolidObjP->getShearModulus();    //获取剪切模量
            double PoissonRatio = ISOSolidObjP->getPoissonRatio();    //获取泊松比
            QString Describe = ISOSolidObjP->getMaterialDescribe();   //材料描述
            int ID = ISOSolidObjP->getDataObjectID();                 //获取数据ID


            //检查字符串输入是否有特殊字符
            m_toolp->CheckString(Name);
            m_toolp->CheckString(Describe);

            //在各向同性材料组下创建具体流体材料属性,并绑定到各向同性组
            m_toolp->CreateNameFromAttr(ISOSolidGroup, i, Name.toStdString());


            //在各向同性材料组下创建具体各向同性材料数据组此时结构 Material/ISOSolid(Aluminum(属性))

            std::tuple<bool, H5::Group>Ret = m_toolp->createGp(ISOSolidGroup, Name);//创建子节点
            if (std::get<0>(Ret) == false) { continue; }

            H5::Group subGroup = std::get<1>(Ret);
            std::vector<bool>writeResultBools;//存储此次写入时返回成功与否数据
            //将材料数据写入到具体材料的属性中
            writeResultBools.push_back(m_toolp->writeGroupAttrStr(subGroup, "Name", Name.toStdString()));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "Density", Density));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "TensileModulus", TensileModulus));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "ShearModulus", ShearModulus));
            writeResultBools.push_back(m_toolp->writeGroupAttrDouble(subGroup, "PoissonRatio", PoissonRatio));
            writeResultBools.push_back(m_toolp->writeGroupAttrStr(subGroup, "Des", Describe.toStdString()));
            writeResultBools.push_back(m_toolp->writeGroupAttrInt(subGroup, "ID", ID));//写入数据对象ID
            bool allBool = this->areAllTrue(writeResultBools);
            if (allBool == false)
            {
                //如果不是全部都为true则，写入失败，写该数据终止
                return false;
            }
        }
        return true;
    }
}



